package com.shop.coupon.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.common.core.domain.Result;
import com.shop.common.security.utils.SecurityUtils;
import com.shop.coupon.domain.Coupon;
import com.shop.coupon.domain.CouponHistory;
import com.shop.coupon.domain.vo.CouponHistoryVo;
import com.shop.coupon.domain.vo.CouponRequest;
import com.shop.coupon.mapper.CouponHistoryVoMapper;
import com.shop.coupon.mapper.CouponMapper;
import com.shop.coupon.service.CouponHistoryVoService;
import com.shop.coupon.service.CouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Service
public class CouponHistoryVoServiceImpl extends ServiceImpl<CouponHistoryVoMapper , CouponHistoryVo> implements CouponHistoryVoService {

    private final CouponHistoryVoMapper couponHistoryVoMapper;

    public CouponHistoryVoServiceImpl(CouponHistoryVoMapper couponHistoryVoMapper) {
        this.couponHistoryVoMapper = couponHistoryVoMapper;
    }

    // 最大处理请求数量
    private static final int MAX_TASK_NUM = 100;

    // 请求队列
    private final Queue<CouponRequest> couponQueue = new LinkedBlockingQueue<>();

    // 初始化方法，启动定时任务处理请求
    public void init() {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            // 获取当前队列大小
            int size = couponQueue.size();
            if (size == 0) {
                return; // 如果队列为空，直接返回
            }
            // 取出部分请求进行处理，避免一次性处理过多请求
            List<CouponRequest> list = new ArrayList<>();
            System.out.println("合并了 [" + size + "] 个请求");
            for (int i = 0; i < size && i < MAX_TASK_NUM; i++) {
                list.add(couponQueue.poll()); // 从队列中取出请求
            }
            // 复制一份请求列表，用于后续查询
            List<CouponRequest> userReqs = new ArrayList<>(list);
            // 批量查询优惠券信息，并将结果返回给请求方
            Map<String, List<CouponHistoryVo>> response = queryCouponByIdBatch(userReqs);
            for (CouponRequest request : list) {
                List<CouponHistoryVo> result = response.getOrDefault(request.getRequestId(), Collections.emptyList());
                request.getCompletableFuture().complete(result); // 将查询结果返回给 CompletableFuture
            }
        }, 100, 10, TimeUnit.MILLISECONDS); // 每隔100毫秒执行一次
    }

    // 批量查询优惠券信息
    private Map<String, List<CouponHistoryVo>> queryCouponByIdBatch(List<CouponRequest> userReqs) {
        // 提取所有用户ID
        List<Long> userIds = userReqs.stream().map(CouponRequest::getUserId).collect(Collectors.toList());
        // 构造查询条件
        QueryWrapper<CouponHistoryVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", userIds);
        // 执行查询
        List<CouponHistoryVo> couponRes = couponHistoryVoMapper.selectList(queryWrapper);
        // 将查询结果按用户ID分组
        Map<Long, List<CouponHistoryVo>> userGroup = couponRes.stream().collect(Collectors.groupingBy(CouponHistoryVo::getId));
        // 构造结果集合
        HashMap<String, List<CouponHistoryVo>> result = new HashMap<>();
        userReqs.forEach(val -> {
            List<CouponHistoryVo> usersList = userGroup.getOrDefault(val.getUserId(), Collections.emptyList());
            result.put(val.getRequestId(), usersList); // 将每个请求对应的查询结果放入结果集合
        });
        return result;
    }


    /**
     * 查询当前用户的优惠券列表
     * @param couponHistoryVo 包含用户信息的优惠券历史对象
     * @return 当前用户的优惠券列表
     */
    @Override
    public Result couponUserSelect(CouponHistoryVo couponHistoryVo) {
        // 获取当前登录用户的ID
        Long userId = SecurityUtils.getUserId();
        // 设置用户ID到优惠券历史对象中
        couponHistoryVo.setMemberId(userId);
        // 查询当前用户的优惠券列表
        List<CouponHistoryVo> userSelect = couponHistoryVoMapper.couponUserSelect(couponHistoryVo.getMemberId());
        return Result.success(userSelect);
    }

    /**
     * 查询已使用的优惠券列表
     * @param couponHistoryVo 包含用户信息的优惠券历史对象
     * @return 包含已使用优惠券列表的成功结果
     */
    @Override
    public Result couponUserSelectUse(CouponHistoryVo couponHistoryVo) {
        // 获取当前登录用户的ID
        Long userId = SecurityUtils.getUserId();
        // 设置用户ID到优惠券历史对象中
        couponHistoryVo.setMemberId(userId);
        // 查询已使用的优惠券列表
        List<CouponHistoryVo> userSelect = couponHistoryVoMapper.couponUserSelectUse(couponHistoryVo.getMemberId());
        return Result.success(userSelect);
    }

    /**
     * 查询已过期的优惠券列表
     * @param couponHistoryVo 包含用户信息的优惠券历史对象
     * @return 包含已过期优惠券列表的成功结果
     */
    @Override
    public Result couponUserSelectExpired(CouponHistoryVo couponHistoryVo) {
        // 获取当前登录用户的ID
        Long userId = SecurityUtils.getUserId();
        // 设置用户ID到优惠券历史对象中
        couponHistoryVo.setMemberId(userId);
        // 查询已过期的优惠券列表
        List<CouponHistoryVo> userSelect = couponHistoryVoMapper.couponUserSelectExpired(couponHistoryVo.getMemberId());
        return Result.success(userSelect);
    }

    /**
     * 删除当前用户的优惠券
     * @param memberId 当前用户的ID
     * @return 成功或失败的结果
     */
    @Override
    public synchronized Result couponUserDelete(Long memberId) {
        // 删除当前用户的优惠券
        int deleteCount = baseMapper.deleteById(memberId);
        return Result.success(deleteCount);
    }

    @Override
    public List couponUser(CouponHistoryVo couponHistoryVo) {
        // 获取当前登录用户的ID
        Long userId = SecurityUtils.getUserId();
        // 设置用户ID到优惠券历史对象中
        couponHistoryVo.setMemberId(userId);
        // 查询当前用户的优惠券列表
        List<CouponHistoryVo> userSelect = couponHistoryVoMapper.couponUserSelect(couponHistoryVo.getMemberId());
        return userSelect;
    }
}
